@@ -13,11 +13,15 @@ module Agents |
||
13 | 13 |
|
14 | 14 |
You must also provide the `username` of the Twitter user to monitor. |
15 | 15 |
|
16 |
+ Set `include_retweets` to `false` to not include retweets (default: `true`) |
|
17 |
+ |
|
16 | 18 |
Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent. |
19 |
+ |
|
20 |
+ Set `starting_at` to the date/time (eg. `Mon Jun 02 00:38:12 +0000 2014`) you want to start receiving tweets from (default: agent's `created_at`) |
|
17 | 21 |
MD |
18 | 22 |
|
19 | 23 |
event_description <<-MD |
20 |
- Events are the raw JSON provided by the Twitter API. Should look something like: |
|
24 |
+ Events are the raw JSON provided by the [Twitter API](https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline). Should look something like: |
|
21 | 25 |
|
22 | 26 |
{ |
23 | 27 |
... every Tweet field, including ... |
@@ -42,38 +46,60 @@ module Agents |
||
42 | 46 |
|
43 | 47 |
default_schedule "every_1h" |
44 | 48 |
|
45 |
- def validate_options |
|
46 |
- unless options['username'].present? && |
|
47 |
- options['expected_update_period_in_days'].present? |
|
48 |
- errors.add(:base, "username and expected_update_period_in_days are required") |
|
49 |
- end |
|
50 |
- end |
|
51 |
- |
|
52 | 49 |
def working? |
53 | 50 |
event_created_within?(options['expected_update_period_in_days']) && !recent_error_logs? |
54 | 51 |
end |
55 | 52 |
|
56 | 53 |
def default_options |
57 | 54 |
{ |
58 |
- 'username' => "tectonic", |
|
59 |
- 'expected_update_period_in_days' => "2" |
|
55 |
+ 'username' => 'tectonic', |
|
56 |
+ 'include_retweets' => 'true', |
|
57 |
+ 'expected_update_period_in_days' => '2' |
|
60 | 58 |
} |
61 | 59 |
end |
62 | 60 |
|
61 |
+ def validate_options |
|
62 |
+ errors.add(:base, "username is required") unless options['username'].present? |
|
63 |
+ errors.add(:base, "expected_update_period_in_days is required") unless options['expected_update_period_in_days'].present? |
|
64 |
+ |
|
65 |
+ if options[:include_retweets].present? && !%w[true false].include?(options[:include_retweets]) |
|
66 |
+ errors.add(:base, "include_retweets must be a boolean value string (true/false)") |
|
67 |
+ end |
|
68 |
+ |
|
69 |
+ if options[:starting_at].present? |
|
70 |
+ Time.parse(options[:starting_at]) rescue errors.add(:base, "Error parsing starting_at") |
|
71 |
+ end |
|
72 |
+ end |
|
73 |
+ |
|
74 |
+ def starting_at |
|
75 |
+ if options[:starting_at].present? |
|
76 |
+ Time.parse(options[:starting_at]) rescue created_at |
|
77 |
+ else |
|
78 |
+ created_at |
|
79 |
+ end |
|
80 |
+ end |
|
81 |
+ |
|
82 |
+ def include_retweets? |
|
83 |
+ options[:include_retweets] != "false" |
|
84 |
+ end |
|
85 |
+ |
|
63 | 86 |
def check |
64 | 87 |
since_id = memory['since_id'] || nil |
65 |
- opts = {:count => 200, :include_rts => true, :exclude_replies => false, :include_entities => true, :contributor_details => true} |
|
88 |
+ opts = {:count => 200, :include_rts => include_retweets?, :exclude_replies => false, :include_entities => true, :contributor_details => true} |
|
66 | 89 |
opts.merge! :since_id => since_id unless since_id.nil? |
67 | 90 |
|
91 |
+ # http://rdoc.info/gems/twitter/Twitter/REST/Timelines#user_timeline-instance_method |
|
68 | 92 |
tweets = twitter.user_timeline(options['username'], opts) |
69 | 93 |
|
70 | 94 |
tweets.each do |tweet| |
71 |
- memory['since_id'] = tweet.id if !memory['since_id'] || (tweet.id > memory['since_id']) |
|
95 |
+ if tweet.created_at >= starting_at |
|
96 |
+ memory['since_id'] = tweet.id if !memory['since_id'] || (tweet.id > memory['since_id']) |
|
72 | 97 |
|
73 |
- create_event :payload => tweet.attrs |
|
98 |
+ create_event :payload => tweet.attrs |
|
99 |
+ end |
|
74 | 100 |
end |
75 | 101 |
|
76 | 102 |
save! |
77 | 103 |
end |
78 | 104 |
end |
79 |
-end |
|
105 |
+end |
@@ -4,10 +4,11 @@ describe Agents::TwitterUserAgent do |
||
4 | 4 |
before do |
5 | 5 |
# intercept the twitter API request for @tectonic's user profile |
6 | 6 |
stub_request(:any, /tectonic/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/user_tweets.json")), :status => 200) |
7 |
- |
|
7 |
+ |
|
8 | 8 |
@opts = { |
9 | 9 |
:username => "tectonic", |
10 | 10 |
:expected_update_period_in_days => "2", |
11 |
+ :starting_at => "Jan 01 00:00:01 +0000 2000", |
|
11 | 12 |
:consumer_key => "---", |
12 | 13 |
:consumer_secret => "---", |
13 | 14 |
:oauth_token => "---", |
@@ -26,4 +27,16 @@ describe Agents::TwitterUserAgent do |
||
26 | 27 |
end |
27 | 28 |
end |
28 | 29 |
|
29 |
-end |
|
30 |
+ describe "#check with starting_at=future date" do |
|
31 |
+ it "should check for changes starting_at a future date, thus not find any" do |
|
32 |
+ opts = @opts.merge({ :starting_at => "Jan 01 00:00:01 +0000 2999", }) |
|
33 |
+ |
|
34 |
+ checker = Agents::TwitterUserAgent.new(:name => "tectonic", :options => opts) |
|
35 |
+ checker.user = users(:bob) |
|
36 |
+ checker.save! |
|
37 |
+ |
|
38 |
+ lambda { checker.check }.should change { Event.count }.by(0) |
|
39 |
+ end |
|
40 |
+ end |
|
41 |
+ |
|
42 |
+end |